package org.apache.ocean;

import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.jdom.Element;

/**
 * 
 * @author jason rutherglen
 */
public class SearchResponse {
	public SortedSet<String> fields;
	public List<CScoreDocument> scoreDocuments;
	public List<OceanDocument> oceanDocuments;
	public CLong start;
	public CLong rows;
	public CLong numFound;
	public CDouble maxScore;
	public FacetResponse facetResponse;
	public HighlightResponse highlightResponse;
	public String cellID;
	public String nodeID;
	public String reportedStatus;
	public CLong queryDuration;
	public String queryString;
	public Date timestamp;
	public URL url;

	public String toString() {
		return ReflectionToStringBuilder.toString(this);
	}

	public SearchResponse(OceanXML oceanXML) throws Exception {
		timestamp = oceanXML.timestamp;
		queryString = oceanXML.getHeaderValue("query");
		start = oceanXML.getHeaderLong("start");
		rows = oceanXML.getHeaderLong("rows");
		numFound = oceanXML.getHeaderLong("numFound");
		cellID = oceanXML.getHeaderValue("cellID");
		nodeID = oceanXML.getHeaderValue("nodeID");
		queryDuration = oceanXML.getHeaderLong("queryDuration");
		url = oceanXML.getHeaderURL("url");
		fields = ClusterUtil.splitSortedSet(oceanXML.getHeaderValue("fields"));
		oceanDocuments = new ArrayList<OceanDocument>();
		for (Element documentElement : XMLUtil.getChildren("document", oceanXML.bodyElement)) {
			oceanDocuments.add(new OceanDocument(documentElement));
		}
		Element highlightsElement = XMLUtil.getChild("highlights", oceanXML.bodyElement);
		if (highlightsElement != null) {
			highlightResponse = new HighlightResponse(highlightsElement);
		}
	}

	public OceanXML toOceanXML(IndexSchema indexSchema) throws Exception {
		OceanXML ocean = new OceanXML();
		ocean.timestamp = new Date();
		ocean.addHeader("query", queryString);
		ocean.addHeader("start", start);
		ocean.addHeader("rows", rows);
		ocean.addHeader("numFound", numFound);
		ocean.addHeader("maxScore", maxScore);
		ocean.addHeader("cellID", cellID);
		ocean.addHeader("nodeID", nodeID);
		ocean.addHeader("queryDuration", queryDuration);
		ocean.addHeader("url", url);
		if (scoreDocuments != null) {
			for (CScoreDocument scoreDocument : scoreDocuments) {
				OceanDocument oceanDocument = scoreDocument.toOceanDocument(indexSchema);
				Element element = oceanDocument.toElement();
				ocean.addBody(element);
			}
		}
		if (oceanDocuments != null && scoreDocuments == null) {
			for (OceanDocument oceanDocument : oceanDocuments) {
				Element element = oceanDocument.toElement();
				ocean.addBody(element);
			}
		}
		if (highlightResponse != null) {
			ocean.addBody(highlightResponse.toElement());
		}
		if (facetResponse != null) {
			ocean.addBody(facetResponse.toElement(indexSchema));
		}
		return ocean;
	}

	public SearchResponse() {
	}
}
